#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
模板匹配应用程序 - 主程序入口
实现OpenCV模板匹配功能的PyQt5应用程序
"""

import sys
import os
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QMessageBox
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qt
from main_window import Ui_MainWindow
from template_matching import TemplateMatchingViewModel

class MainApp(QMainWindow):
    """主应用程序类"""
    
    def __init__(self):
        """初始化应用程序"""
        super().__init__()
        
        # 设置UI
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        
        # 创建模板匹配视图模型
        self.view_model = TemplateMatchingViewModel()
        
        # 绑定按钮事件
        self.ui.btn_load_image.clicked.connect(self.load_source_image)
        self.ui.btn_load_template.clicked.connect(self.load_template_image)
        self.ui.btn_draw_template.clicked.connect(self.draw_template)
        self.ui.btn_save_template.clicked.connect(self.save_template)
        self.ui.btn_match.clicked.connect(self.perform_matching)
        
        # 绑定匹配方法选择事件
        self.ui.method_combo.currentIndexChanged.connect(self.update_matching_method)
        
        # 设置窗口标题
        self.setWindowTitle("OpenCV Template Matching Demo")
        
    def load_source_image(self):
        """加载源图像"""
        image_path, _ = QFileDialog.getOpenFileName(
            self, "选择图像", "", "图像文件 (*.png *.jpg *.jpeg *.bmp)"
        )
        
        if image_path:
            self.view_model.load_source_image(image_path)
            if self.view_model.source_image is not None:
                self.ui.image_view.set_image(self.view_model.source_image)
                
    def load_template_image(self):
        """加载模板图像"""
        image_path, _ = QFileDialog.getOpenFileName(
            self, "选择模板", "", "图像文件 (*.png *.jpg *.jpeg *.bmp)"
        )
        
        if image_path:
            self.view_model.load_template_image(image_path)
            if self.view_model.template_image is not None:
                self.ui.template_view.set_image(self.view_model.template_image)
                
    def draw_template(self):
        """从绘制矩形区域创建模板"""
        if self.view_model.source_image is None:
            QMessageBox.warning(self, "警告", "请先加载源图像")
            return
            
        # 获取选择区域并更新模板图像
        template_img = self.ui.image_view.crop_selected_region()
        if template_img is not None:
            self.view_model.set_template_image(template_img)
            self.ui.template_view.set_image(self.view_model.template_image)
        else:
            QMessageBox.warning(self, "警告", "请先在源图像上选择区域")
            
    def save_template(self):
        """保存模板图像"""
        if self.view_model.template_image is None:
            QMessageBox.warning(self, "警告", "没有模板可保存")
            return
            
        file_path, _ = QFileDialog.getSaveFileName(
            self, "保存模板", "template.png", "PNG图像 (*.png)"
        )
        
        if file_path:
            try:
                self.view_model.save_template_image(file_path)
                QMessageBox.information(self, "成功", f"模板已保存到: {file_path}")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"保存模板失败: {str(e)}")
                
    def update_matching_method(self, index):
        """更新匹配方法"""
        self.view_model.current_method_index = index
        
    def perform_matching(self):
        """执行模板匹配操作"""
        if self.view_model.source_image is None or self.view_model.template_image is None:
            QMessageBox.warning(self, "警告", "请确保已加载源图像和模板图像")
            return
        
        # 获取选择的匹配方法索引
        method_index = self.ui.method_combo.currentIndex()
        
        # 执行匹配并显示结果
        self.view_model.match_template(method_index)
        
        # 显示匹配结果图像
        if self.view_model.result_image is not None:
            self.ui.image_view.set_image(self.view_model.result_image)
        
        # 显示热图
        if self.view_model.heatmap_image is not None:
            self.ui.heatmap_view.set_image(self.view_model.heatmap_image)
            
        # 显示详细匹配数据
        self.update_result_info()

    def update_result_info(self):
        """更新结果信息显示"""
        if not hasattr(self.view_model, 'last_match_results'):
            return
            
        # 获取匹配结果数据
        results = self.view_model.last_match_results
        if not results:
            return
            
        # 格式化结果信息
        method_name = self.view_model.matching_methods[self.view_model.current_method_index][0]
        score = results['score']
        position = results['position']
        mean = results['mean']
        std_dev = results['std_dev']
        
        # 构建详细信息文本
        info_text = f"匹配方法: {method_name}\n"
        info_text += f"匹配分数: {score:.6f}\n"
        info_text += f"匹配位置: ({position[0]}, {position[1]})\n"
        info_text += f"统计均值: {mean:.6f}\n"
        info_text += f"标准差: {std_dev:.6f}\n"
        
        # 添加匹配解释
        is_min_method = self.view_model.current_method_index < 2  # SqDiff 和 SqDiffNormed
        if is_min_method:
            quality = "最小值表示最佳匹配"
            if score < 0.1:
                evaluation = "极佳匹配"
            elif score < 0.3:
                evaluation = "良好匹配"
            else:
                evaluation = "可能匹配"
        else:
            quality = "最大值表示最佳匹配"
            if score > 0.9:
                evaluation = "极佳匹配"
            elif score > 0.7:
                evaluation = "良好匹配"
            else:
                evaluation = "可能匹配"
                
        info_text += f"\n评估: {evaluation}\n({quality})"
        
        # 更新结果标签
        self.ui.result_label.setText(info_text)

def main():
    """主函数"""
    app = QApplication(sys.argv)
    window = MainApp()
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
